---
description:
  Generate executable schema for SOAP services with GraphQL Mesh SOAP handler. Consume WSDL files
  and get started easily.
---

import { Callout } from '@theguild/components'

# SOAP

This handler allows you to consume [SOAP](https://soapui.org) `WSDL` files and generate a remote
executable schema for those services.

## How to use?

To get started, install the handler library:

```sh npm2yarn
npm i @omnigraph/soap
```

Then you can import the library in your configuration file, and define your SOAP source;

```ts filename="mesh.config.ts" {2,7-9}
import { defineConfig } from '@graphql-mesh/compose-cli'
import { loadSOAPSubgraph } from '@omnigraph/soap'

export const composeConfig = defineConfig({
  subgraphs: [
    {
      sourceHandler: loadSOAPSubgraph('CountryInfo', {
        source:
          'http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL'
      })
    }
  ]
})
```

## Headers

If you want to add SOAP headers to the request body like below;

```xml
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:header="http://foo.com/">
   <soap:Header>
      <header:MyHeader>
         <header:UserName>user</header:UserName>
         <header:Password>password</header:Password>
      </header:MyHeader>
   </soap:Header>
```

You can add the headers to the configuration like below;

```ts filename="mesh.config.ts" {2,7-9}
import { defineConfig } from '@graphql-mesh/compose-cli'
import { loadSOAPSubgraph } from '@omnigraph/soap'

export const composeConfig = defineConfig({
  subgraphs: [
    {
      sourceHandler: loadSOAPSubgraph('CountryInfo', {
        source:
          'http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL',
        soapHeaders: {
          // The name of the alias to be used in the envelope for header components
          alias: 'header',
          namespace: 'http://foo.com',
          headers: {
            MyHeader: {
              UserName: 'user',
              Password: 'password'
              // You can also use environment variables, so it will get the value on runtime
              Password: '{env.SOAP_PASSWORD}'
            }
          }
        }
      })
    }
  ]
})
```

<Callout>
  [You can find a working example here](
  https://github.com/ardatan/graphql-mesh/tree/main/examples/v1-next/soap-demo )
</Callout>

## Custom Body Alias

You can now choose the name of the alias you want to use for SOAP body;

```ts filename="mesh.config.ts" {4}
import { defineConfig } from '@graphql-mesh/compose-cli'
import { loadSOAPSubgraph } from '@omnigraph/soap'

export const composeConfig = defineConfig({
  subgraphs: [
    {
      sourceHandler: loadSOAPSubgraph('CountryInfo', {
        source:
          'http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL',
        bodyAlias: 'my-body'
      })
    }
  ]
})
```

Then it will generate a body like below by using the alias;

```xml
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:my-body="http://foo.com/">
   <soap:Body>
      <my-body:Foo>
          <my-body:Bar>baz</my-body:Bar>
      </my-body:Foo>
   </soap:Body>
</soap:Envelope>
```

## Custom SOAP namespace

By default, Mesh detects the namespace from the WSDL file.

For SOAP 1.1, it is set to `http://schemas.xmlsoap.org/soap/envelope/` and for SOAP 1.2, it is set
to `http://www.w3.org/2003/05/soap-envelope`.

If you want to use a custom namespace, you can set it like below;

```ts
import { defineConfig } from '@graphql-mesh/compose-cli'
import { loadSOAPSubgraph } from '@omnigraph/soap'

export const composeConfig = defineConfig({
  subgraphs: [
    {
      sourceHandler: loadSOAPSubgraph('CountryInfo', {
        source:
          'http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL',
        soapNamespace: 'http://foo.com/schemas/soap/envelope'
      })
    }
  ]
})
```
